package gwt.trading.client;

import gwt.trading.client.geometry.Point;
import gwt.trading.client.geometry.Size;
import gwt.trading.client.util.ColorEnum;

/**
 * @author Iulian Costan (iulian.costan@gmail.com)
 *
 */
public class DrawingArea {

	private TradingChartSettings chartSettings;
	private DrawingAreaSettings areaSettings;
	private DrawingBoard drawingBoard;

	private AxisCoordinate axisCoordinate;

	DrawingArea(VerticalConstrainter masterAttachable, TradingChartSettings chartSettings,
			DrawingAreaSettings areaSettings, Point offset) {
		this.chartSettings = chartSettings;
		this.areaSettings = areaSettings;

		Size size = new Size(chartSettings.getWidth(), areaSettings.getHeight());
		this.drawingBoard = new DrawingBoard(offset, size);

		// vertical axis
		VerticalAxis verticalAxis = masterAttachable.getVerticalAxis();
		DrawingBoard verticalAxisDrawingBoard = getVerticalAxisBoard(chartSettings, verticalAxis);
		verticalAxis.setDrawingBoard(verticalAxisDrawingBoard);

		// horizontal axis
		HorizontalAxis horizontalAxis = masterAttachable.getHorizontalAxis();
		DrawingBoard horizontalAxisDrawingBoard = getHorizontalAxisBoard(horizontalAxis, chartSettings, areaSettings);
		horizontalAxis.setDrawingBoard(horizontalAxisDrawingBoard);

		// calculate area's drawing manager
		Translator translator = new Translator(new Point(offset.getX(), offset.getY()));
		Transformer transformer = getTransformer(chartSettings, areaSettings, verticalAxis, horizontalAxis);
		DrawingManager drawingManager = new DrawingManager(transformer, translator);

		// init axis
		verticalAxis.setDrawingManager(drawingManager);
		horizontalAxis.setDrawingManager(drawingManager);

		// create axis coordinate
		axisCoordinate = new AxisCoordinate(verticalAxis, horizontalAxis, drawingManager);
		axisCoordinate.attach(masterAttachable);
	}

	private DrawingBoard getHorizontalAxisBoard(HorizontalAxis horizontalAxis, TradingChartSettings chartSettings,
			DrawingAreaSettings areaSettings) {
		int dx = 0;
		int dy = areaSettings.getHeight() - horizontalAxis.getHeight();
		return drawingBoard.shrink(dx, dy, chartSettings.getWidth(), drawingBoard.getSize().getHeight());
	}

	private DrawingBoard getVerticalAxisBoard(TradingChartSettings chartSettings, VerticalAxis verticalAxis) {
		int dx = chartSettings.getWidth() - verticalAxis.getWidth();
		int dy = 0;
		return drawingBoard.shrink(dx, dy, verticalAxis.getWidth(), drawingBoard.getSize().getHeight());
	}

	private Transformer getTransformer(TradingChartSettings chartSettings, DrawingAreaSettings areaSettings,
			VerticalAxis verticalAxis, HorizontalAxis horizontalAxis) {

		int xMax = horizontalAxis.getPeriods();
		int xSize = chartSettings.getWidth() - verticalAxis.getWidth();
		
		float yMin = verticalAxis.getMin();
		float yMax = verticalAxis.getMax();
		int ySize = areaSettings.getHeight();

		if (horizontalAxis != null) {
			ySize -= horizontalAxis.getHeight();
		}

		Transformer transformer = new Transformer(xMax, xSize, yMin, yMax, ySize, areaSettings.getPadding());
		return transformer;
	}

	public void attach(Attachable attachable) {
		axisCoordinate.attach(attachable);
	}

	void draw(final Renderer renderer) {
		drawArea(renderer);
		axisCoordinate.draw(renderer);
	}

	private void drawArea(Renderer renderer) {
		int width = chartSettings.getWidth();
		int height = areaSettings.getHeight();
		ColorEnum bgColor = areaSettings.getBackgroundColor();

		renderer.fillBackground(drawingBoard.getTranslator().getOrigin(), width, height, bgColor);
	}

	public Attachable getAttachable(String id) {
		return axisCoordinate.getAttachable(id);		
	}
	
	public Attachable remove(String id) {
		return axisCoordinate.remove(id);
	}

}
